package com.hjy.backend;


import com.hjy.backend.dataManager.DataManager;
import com.hjy.backend.server.Server;
import com.hjy.backend.tableManager.TableManager;
import com.hjy.backend.transactionManager.TransactionManager;
import com.hjy.backend.utils.Panic;
import com.hjy.backend.versionManager.VersionManager;
import com.hjy.backend.versionManager.VersionManagerImpl;
import com.hjy.common.error.Error;
import org.apache.commons.cli.*;

/**
 * 后端启动器
 */
public class Launcher {

    public static final int port = 9999;

    // 默认内存 64 MB
    public static final long DEFAULT_MEM = (1 << 20) * 64;
    public static final long KB = 1 << 10;
    public static final long MB = 1 << 20;
    public static final long GB = 1 << 30;

    public static void main(String[] args) throws ParseException {
        // DBPath = C:\my\E\Java_document\JyDB\JyDB\tmp
        Options options = new Options();
        options.addOption("open", true, "-open DBPath");
        options.addOption("create", true, "-create DBPath");
        options.addOption("mem", true, "-mem 64MB");
        CommandLineParser parser = new DefaultParser();
        CommandLine cmd = parser.parse(options, args);

        if (cmd.hasOption("open")) {
            openDB(cmd.getOptionValue("open"), parseMem(cmd.getOptionValue("mem")));
            return;
        }
        if (cmd.hasOption("create")) {
            createDB(cmd.getOptionValue("create"));
            return;
        }
        System.out.println("Usage: launcher (open|create) DBPath");
    }

    /**
     * 创建数据库
     * @param path
     */
    private static void createDB(String path) {
        // 事务管理器
        TransactionManager tm = TransactionManager.create(path);
        // 数据管理器
        DataManager dm = DataManager.create(path, DEFAULT_MEM, tm);
        // 版本管理器
        VersionManager vm = new VersionManagerImpl(tm, dm);
        // 表管理模块
        TableManager.create(path, vm, dm);
        tm.close();
        dm.close();
    }

    /**
     * 加载数据库
     * @param path
     * @param mem
     */
    private static void openDB(String path, long mem) {
        // 事务管理器, 加载 .xid 文件
        TransactionManager tm = TransactionManager.open(path);
        // 数据管理器, 验证上次数据库是否正常关闭, 同时初始化 Index
        DataManager dm = DataManager.open(path, mem, tm);
        // 版本管理器
        VersionManager vm = new VersionManagerImpl(tm, dm);
        // 表管理模块, 加载出 .bt 文件
        TableManager tbm = TableManager.open(path, vm, dm);
        // 开始服务
        new Server(port, tbm).start();
    }

    /**
     * 解析内存大小
     * @param memStr
     * @return
     */
    private static long parseMem(String memStr) {
        if (memStr == null || "".equals(memStr)) {
            return DEFAULT_MEM;
        }
        if (memStr.length() < 2) {
            Panic.panic(Error.InvalidMemException);
        }
        String unit = memStr.substring(memStr.length() - 2);
        long memNum = Long.parseLong(memStr.substring(0, memStr.length() - 2));
        switch (unit) {
            case "KB":
                return memNum * KB;
            case "MB":
                return memNum * MB;
            case "GB":
                return memNum * GB;
            default:
                Panic.panic(Error.InvalidMemException);
        }
        return DEFAULT_MEM;
    }
}
